﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using EntitiesLayer;
using DAL;
using DAL.Repositories;
using Exceptions;
using System.Net.Mail;

namespace BLL
{
    public class Gestor
    {

        private UnitOfWork UoW = new UnitOfWork();

        #region obtenerGimnasio
        public Gimnasio ObtenerGimnasio()
        {
            return UoW.GimnasioRepository.GetById(0);
        }
        #endregion
        #region listarEjercicios
        public IEnumerable<Ejercicio> listarEjercicios()
        {
            return UoW.EjercicioRepository.GetAll();
        }
        #endregion listarEjercicios

        #region musculos
        public IEnumerable<Musculo> listarMusculos()
        {
            return UoW.MusculoRepository.GetAll();
        }

        public Musculo consultarMusculo(int pid)
        {
            return UoW.MusculoRepository.GetById(pid);
        }

        public void registrarMusculo(String pnombre, String pirrigacion, String porigen, String pinsercion, String pinervacion)
        {
            Musculo objMusculo = new Musculo(pnombre, pirrigacion, porigen, pinsercion, pinervacion);
            UoW.MusculoRepository.Insert(objMusculo);
            UoW.MusculoRepository.Save();
            UoW.MusculoRepository.Clear();
        }

        public void modificarMusculo(int pid, String pnombre, String pirrigacion, String porigen, String pinsercion, String pinervacion)
        {
            Musculo objMusculo = new Musculo(pid, pnombre, pirrigacion, porigen, pinsercion, pinervacion);
            UoW.MusculoRepository.Update(objMusculo);
            UoW.MusculoRepository.Save();
            UoW.MusculoRepository.Clear();
        }
        #endregion musculos



        #region listaPermisos
        public IEnumerable<int> listaPermisos(int pidRol)
        {
            return UoW.RolRepository.GetPermisos(pidRol);
        }
        #endregion listarMusculos

        #region agregarEjercicio
        //metodo para registrar un ejercicio
        public void agregarEjercicio(String pnombreComun, String pnombreOpcional, String pcodigo, byte[] pimagenInicial, byte[] pimagenFinal, String pnombreMusculoPrincipal, List<Musculo> plistaMusculos, String perroresComunes, String pindicacionesGenerales)
        {
            try
            {
                Ejercicio objEjercicio = new Ejercicio(pnombreComun, pnombreOpcional, pcodigo, pimagenInicial, pimagenFinal, pnombreMusculoPrincipal, plistaMusculos, perroresComunes, pindicacionesGenerales);
                if (objEjercicio.IsValid)
                {
                    UoW.EjercicioRepository.Insert(objEjercicio);
                    UoW.EjercicioRepository.Save();
                    UoW.EjercicioRepository.Clear();
                }
                else
                {
                    StringBuilder sb = new StringBuilder();
                    foreach (RuleViolation rv in objEjercicio.GetRuleViolations())
                    {
                        sb.AppendLine(rv.ErrorMessage);
                    }
                    throw new BusinessLogicException(sb.ToString());
                }
            }
            catch (Exception ex)
            {

                throw ex;
            }
        }

        #endregion


        #region buscarEjercicio
        //metodo para buscar un ejercicio en especifico
        public Ejercicio buscarEjercicio(int pidEjercicio)
        {
            return UoW.EjercicioRepository.GetById(pidEjercicio);
        }



        #endregion

        #region buscarRol
        //metodo para buscar un ejercicio en especifico
        public Rol buscarRol(int pidRol)
        {
            return UoW.RolRepository.GetById(pidRol);
        }



        #endregion

        #region consultarMusculosAsociados
        //metodo para consultar los musculos asociados a un ejercicio
        public IEnumerable<Musculo> consultarMusculosAsociados(int idEjercicio)
        {
            return UoW.EjercicioRepository.GetMusculosAsociados(idEjercicio);
        }
        #endregion consultarMusculosAsociados

        #region modificarEjercicio
        //metodo para modificar un ejercicio
        public void modificarEjercicio(int pidEjercicio, String pnombreComun, String pnombreOpcional, String pcodigo, byte[] pimagenInicial, byte[] pimagenFinal, String pnombreMusculoPrincipal, List<Musculo> plistaMusculos, String perroresComunes, String pindicacionesGenerales)
        {
            try
            {
                //consultar un ejercicio por el id del mismo
                Ejercicio objEjercicio = UoW.EjercicioRepository.GetById(pidEjercicio);

                //setea los valores al ejercicio cargado
                objEjercicio.NombreComun = pnombreComun;
                objEjercicio.NombreOpcional = pnombreOpcional;
                objEjercicio.Codigo = pcodigo;
                objEjercicio.PosicionInicial = pimagenInicial;
                objEjercicio.PosicionFinal = pimagenFinal;
                objEjercicio.MusculoPrincipal = pnombreMusculoPrincipal;
                objEjercicio.ListaMusculos = plistaMusculos;
                objEjercicio.IndicacionesGenerales = pindicacionesGenerales;
                objEjercicio.ErroresComunes = perroresComunes;

                if (objEjercicio.IsValid)
                {
                    UoW.EjercicioRepository.Update(objEjercicio);
                    UoW.EjercicioRepository.Save();
                    UoW.EjercicioRepository.Clear();
                }
                else
                {
                    StringBuilder sb = new StringBuilder();
                    foreach (RuleViolation rv in objEjercicio.GetRuleViolations())
                    {
                        sb.AppendLine(rv.ErrorMessage);
                    }
                    throw new BusinessLogicException(sb.ToString());
                }
            }
            catch (Exception ex)
            {

                throw ex;
            }
        }

        #endregion

        #region filtrarListaEjercicios
        //metodo para filtrar la lista de ejercicios
        public IEnumerable<Ejercicio> filtrarListaEjercicios(String ptextoAfiltrar)
        {
            return UoW.EjercicioRepository.FiltrarListaEjercicios(ptextoAfiltrar);
        }

        #endregion filtrarListaEjercicios

        #region filtrarListaRoles
        //metodo para filtrar la lista de ejercicios
        public IEnumerable<Rol> filtrarListaRoles(String ptextoAfiltrar)
        {
            return UoW.RolRepository.FiltrarListaRoles(ptextoAfiltrar);
        }

        #endregion filtrarListaRoles

        #region listarRoles
        public IEnumerable<Rol> listarRoles()
        {
            return UoW.RolRepository.GetAll();
        }
        #endregion listarRoles

        #region agregarRol
        //metodo para registrar un ejercicio
        public void agregarRol(String pcodigo, String pdescripcion, List<int> plistaPermisos)
        {
            try
            {
                Rol objRol = new Rol(pcodigo, pdescripcion, plistaPermisos);
                if (objRol.IsValid)
                {
                    UoW.RolRepository.Insert(objRol);
                    UoW.RolRepository.Save();
                    UoW.RolRepository.Clear();
                }
                else
                {
                    StringBuilder sb = new StringBuilder();
                    foreach (RuleViolation rv in objRol.GetRuleViolations())
                    {
                        sb.AppendLine(rv.ErrorMessage);
                    }
                    throw new BusinessLogicException(sb.ToString());
                }
            }
            catch (Exception ex)
            {

                throw ex;
            }
        }

        #endregion agregarRol

        #region modificarRol
        //metodo para registrar un ejercicio
        public void modificarRol(int pidRol, String pcodigo, String pdescripcion, List<int> plistaPermisos)
        {
            try
            {
                Rol objRol = new Rol(pidRol, pcodigo, pdescripcion, plistaPermisos);
                if (objRol.IsValid)
                {
                    UoW.RolRepository.Update(objRol);
                    UoW.RolRepository.Save();
                    UoW.RolRepository.Clear();
                }
                else
                {
                    StringBuilder sb = new StringBuilder();
                    foreach (RuleViolation rv in objRol.GetRuleViolations())
                    {
                        sb.AppendLine(rv.ErrorMessage);
                    }
                    throw new BusinessLogicException(sb.ToString());
                }
            }
            catch (Exception ex)
            {

                throw ex;
            }
        }

        #endregion modificarRol

        #region consultarPagos
            
        public Pago UltimoPagoUsuario(Usuario pusuario){

            return UoW.PagoRepository.getUltimoPagoUsuario(pusuario);
        }
        #endregion
        
        public TiposPagos getPrecios(int pid) 
        {
            return UoW.PreciosRepository.GetById(pid);
        }
 
        public void RegistrarPagoEfectivo(int pidUsuario, int pTipoPago, int pformaPago,
                    String pfechaInicio, String pfechaFinal, double ptotalPago)
        {
            Pago pago = null;
            try
            {
                pago = new Pago()
                {
                    Id = 0,
                    IdUsuario = pidUsuario,
                    TipoPago = pTipoPago,
                    FormaPago = pformaPago,
                    FechaPago = pfechaInicio,
                    FechaFin = pfechaFinal,
                    totalPago = ptotalPago
                };

                UoW.PagoRepository.Insert(pago);
                UoW.PagoRepository.Save();
            }
            catch (Exception)
            {
                //aqui va la excepcion
            }
        }


        public void RegistrarPagoTarjeta(int pidUsuario, int pTipoPago, int pformaPago,
                   String pfechaInicio, String pfechaFinal, double ptotalPago,
                   String pnombreTarjeta, String pnumeroTarjeta, String pcodigoSeguridad,
                   String pfechaVencimiento)
        {
            Pago pago = null;
            try
            {
                pago = new Pago()
                {
                    Id = 0,
                    IdUsuario = pidUsuario,
                    TipoPago = pTipoPago,
                    FormaPago = pformaPago,
                    FechaPago = pfechaInicio,
                    FechaFin = pfechaFinal,
                    totalPago = ptotalPago
                };

                UoW.PagoRepository.Insert(pago);
                UoW.PagoRepository.Save();

                UoW.PagoRepository.registrarTarjeta(pnombreTarjeta, pnumeroTarjeta, pcodigoSeguridad, pfechaVencimiento);
            }
            catch (Exception)
            {
                //aqui va la excepcion
            }
        } 

        #region registrarMaquina
        public void registrarMaquina(String pnombre, String pnumMaquina, String pnumActivo, bool pestado)
        {
            try
            {
                Maquina objMaquina = new Maquina(pnombre, pnumMaquina, pnumActivo, pestado);
                if (objMaquina.IsValid)
                {
                    UoW.MaquinaRepository.Insert(objMaquina);
                    UoW.MaquinaRepository.Save();
                }
                else
                {
                    StringBuilder sb = new StringBuilder();
                    foreach (RuleViolation rv in objMaquina.GetRuleViolations())
                    {
                        sb.AppendLine(rv.ErrorMessage);
                    }
                    throw new BusinessLogicException(sb.ToString());
                }
            }
            catch (Exception ex)
            {

                throw ex;
            }
        }
        #endregion registrarMaquina

        #region listarMaquinas
        public IEnumerable<Maquina> listarMaquinas()
        {
            return UoW.MaquinaRepository.GetAll();
        }
        #endregion listarMaquinas

        #region buscarMaquina
        public Maquina buscarMaquina(int pid)
        {
            Maquina objMaquina = UoW.MaquinaRepository.GetById(pid);

            return objMaquina;
        }
        #endregion buscarMaquina

        #region modificarMaquina
        public void modificarMaquina(int pid, String pnombre, String pnumMaquina, String pnumActivo, bool pestado)
        {
            try
            {
                Maquina objMaquina = new Maquina(pid, pnombre, pnumMaquina, pnumActivo, pestado);
                if (objMaquina.IsValid)
                {
                    UoW.MaquinaRepository.Update(objMaquina);
                    UoW.MaquinaRepository.Save();
                }
                else
                {
                    StringBuilder sb = new StringBuilder();
                    foreach (RuleViolation rv in objMaquina.GetRuleViolations())
                    {
                        sb.AppendLine(rv.ErrorMessage);
                    }
                    throw new BusinessLogicException(sb.ToString());
                }
            }
            catch (Exception ex)
            {

                throw ex;
            }
        }
        #endregion modificarMaquina

        #region notificarPago
        public void notificarPago(String pcorreoCliente, String pmonto, String pnombreUsuario)
        {
            MailMessage msj = new MailMessage();
            msj.From = new MailAddress("mygetfitgym@gmail.com");
            msj.To.Add(pcorreoCliente);

            msj.Subject = "GetFit Notificación de pago";
            msj.SubjectEncoding = System.Text.Encoding.UTF8;

            msj.Body =
                "Estimado " + pnombreUsuario
                + ":\n \n \nSe ha realizado el pago de la cuota exitosamente.\n"
                + "El monto de pago es de: " + "₡" + pmonto
                + "\n \n \n \n"
                + "Saludos coordiales del equipo de GetFit"
                + "\nIridium Systems";

            msj.BodyEncoding = System.Text.Encoding.UTF8;
            msj.IsBodyHtml = false;

            SmtpClient mClient = new SmtpClient();
            mClient.Credentials = new System.Net.NetworkCredential("mygetfitgym@gmail.com", "getfit12345");
            mClient.Port = 587;
            mClient.EnableSsl = true;
            mClient.Host = "smtp.gmail.com";

            try
            {
                //Enviamos el mensaje      
                mClient.Send(msj);
            }
            catch (System.Net.Mail.SmtpException ex)
            {
                //Aquí gestionamos los errores al intentar enviar el correo
            }
        }
        #endregion notificarPago

        #region gimnasio

        public Gimnasio consultarGimnasio()
        {
            return UoW.GimnasioRepository.GetAll().First();
        }

        public void modificarGimnasio(int pid, String pnombre, String pubicacion, String ptelefono, String pcedulaJuridica, Byte[] plogo)
        {
            Gimnasio objGimnasio = new Gimnasio(pid, pnombre, pubicacion, ptelefono, pcedulaJuridica, plogo);
            UoW.GimnasioRepository.Update(objGimnasio);
        }

        #endregion
    }
}
